package com.ruoyi.quartz.controller;

import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * 简化版一键关机接口（无安全校验，仅用于测试）
 */
@RestController
@RequestMapping("/system")
public class SystemController {
    private static final Logger log = LoggerFactory.getLogger(SystemController.class);

    /**
     * 调用此接口将执行系统关机
     */
    @Anonymous
    @GetMapping("/shutdown")
    public AjaxResult shutdownSystem() {
        try {
            // 获取操作系统类型
            String osName = System.getProperty("os.name").toLowerCase();
            Process process = null;
            // 根据操作系统执行对应关机命令
            if (osName.contains("windows")) {
                // Windows系统：立即关机（-s表示关机，-t 0表示延迟0秒）
                process = Runtime.getRuntime().exec("shutdown -s -t 0");}
            // 等待命令执行并获取退出码（0表示成功）
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                log.info("关机命令已执行，系统即将关闭");
                return AjaxResult.success("关机命令已执行，系统即将关闭");
            } else {
                return AjaxResult.error("关机命令执行失败，退出码：" + exitCode);
            }

        } catch (IOException e) {
            log.error("执行关机命令时发生IO异常", e);
            return AjaxResult.error("执行失败：" + e.getMessage());
        } catch (InterruptedException e) {
            log.error("关机命令执行被中断", e);
            Thread.currentThread().interrupt(); // 恢复中断状态
            return AjaxResult.error("执行被中断：" + e.getMessage());
        }
    }
    @Anonymous
    @PostMapping("/runcommand")
    public AjaxResult batchRun(@RequestBody Map<String, Object> params) {
        List<String> commands = (List<String>) params.get("commands");
        if (commands == null || commands.isEmpty()) {
            return AjaxResult.error("命令列表不能为空");
        }

        String osName = System.getProperty("os.name").toLowerCase();
        for (int i = 0; i < commands.size(); i++) {
            String originalCmd = commands.get(i);
            String cmd = originalCmd;
            // 1. 修复Windows内置命令执行问题：调用cmd /c执行
            if (osName.contains("windows")) {
                // 对Windows命令进行包装，处理内置命令（如dir、cd）
                cmd = "cmd /c \"" + originalCmd.replace("\"", "\\\"") + "\"";
            }
            try {
                log.info("开始执行第{}条命令：原命令={}，实际执行={}", i + 1, originalCmd, cmd);
                Process process = Runtime.getRuntime().exec(cmd);

                // 2. 修复中文乱码：Windows用GBK，Linux/Mac用UTF-8
                String charset = osName.contains("windows") ? "GBK" : "UTF-8";
                String output = readProcessOutput(process.getInputStream(), charset);
                String error = readProcessOutput(process.getErrorStream(), charset);

                int exitCode = process.waitFor();
                if (exitCode == 0) {
                    log.info("第{}条命令执行成功，输出：\n{}", i + 1, output);
                } else {
                    log.error("第{}条命令执行失败，错误码：{}，错误信息：\n{}",
                            i + 1, exitCode, error);
                    return AjaxResult.error("第" + (i + 1) + "条命令执行失败：" + error);
                }
            } catch (Exception e) {
                String errorMsg = "执行第" + (i + 1) + "条命令（" + originalCmd + "）时异常：" + e.getMessage();
                log.error(errorMsg, e);
                return AjaxResult.error(errorMsg);
            }
        }
        return AjaxResult.success("所有命令执行完成");
    }

    // 重载工具方法：支持指定编码
    private String readProcessOutput(InputStream inputStream, String charset) throws IOException {
        // 根据系统指定编码读取流，解决中文乱码
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(inputStream, charset))) {
            StringBuilder output = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line).append("\n");
            }
            return output.toString().trim();
        }
    }
}
